home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* kpres
- /* SUMMARY
- /* k-protocol presentation layer
- /* PACKAGE
- /* uucp across thenet
- /* SYNOPSIS
- /* #include "kp.h"
- /*
- /* kopen(fd)
- /* int fd;
- /*
- /* kwrite(fd,buf,len)
- /* int fd,len;
- /* char *buf;
- /*
- /* kread(fd,buf,len)
- /* int fd,len;
- /* char *buf;
- /*
- /* kclose(fd)
- /* int fd;
- /* DESCRIPTION
- /* This section contains functions that imitate standard unix
- /* unbuffered i/o facilities. A status code of FAIL is returned when
- /* the network partner wants to terminate the protocol, or when the
- /* the transmission error rate is excessive.
- /*
- /* Eight-bit data bytes are transported as harmless six-bit data bytes
- /* in the ASCII range 32 through 95. This introduces an overhead of 33%.
- /* For textfiles, this is hardly worse than kermit (typical overhead
- /* 10 %). For binary files the overhead is much less than with kermit
- /* (typical overhead 60%).
- /*
- /* Kopen() sets up the terminal characteristics of the specified file
- /* descriptors (no echo, raw, tandem). Always returns zero status.
- /*
- /* Kwrite() attempts to send the bytes in buf. A zero-length buffer
- /* should be written to indicate an end-of-file condition. Return status:
- /* the number of bytes requested, or FAIL.
- /*
- /* Kread() attempts to read the requested number of bytes. Status code:
- /* the number of bytes actually read, or FAIL. A read of zero bytes
- /* normally indicates an end-of-file condition (see kwrite).
- /*
- /* Kclose() sends a protocol abort sequence to the network partner.
- /* This function should be called to terminate the k protocol driver
- /* at the other end, or to confirm reception of a protocol abort sequence.
- /* Kclose always returns zero exit status.
- /*
- /* The function kfail() is called by the strategy layer functions to
- /* indicate protocol failure or termination.
- /* FUNCTIONS AND MACROS
- /* kwproto, krproto, kclsproto
- /* BUGS
- /* Zero byte read/writes are a clumsy way to handle end-of-files.
- /* They have been implemented for the sake of compatibility with uucico.
- /* AUTHOR(S)
- /* Wietse Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Mon Feb 3 11:14:13 MET 1986
- /* LAST MODIFICATION
- /* 90/01/22 13:01:57
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #ifdef unix
- # ifdef SIII
- # include <termio.h>
- # else
- # include <sgtty.h>
- # endif
- #endif
- #include <setjmp.h>
- #include "kp.h"
-
- static jmp_buf Failbuf;
-
- kfail()
- {
- longjmp(Failbuf,TRUE);
- }
-
- kopen(fd)
- int fd;
- {
- #ifdef unix
- # ifdef SIII
- struct termio ttymode;
-
- ioctl(fd,TCGETA,&ttymode);
- ttymode.c_iflag = IXOFF|IXON|ISTRIP;
- ttymode.c_cc[VMIN] = 1;
- ttymode.c_cc[VTIME] = 0;
- ioctl(fd,TCSETA,&ttymode);
- # else
- struct sgttyb ttymode;
-
- gtty(fd,&ttymode);
- ttymode.sg_flags |= (TANDEM|RAW);
- ttymode.sg_flags &= ~(ECHO|CBREAK);
- stty(fd,&ttymode);
- # endif
- #else
- xioctl(1);
- #endif
- return 0;
- }
-
- kwrite(fd,buf,len)
- int fd;
- register char *buf;
- register int len;
- {
- static char packbuf[MAXPACKSIZ];
- static char *packptr = packbuf;
- register int c,i,rest,shift;
-
- /* set error trap */
-
- if (setjmp(Failbuf))
- return FAIL;
-
- /* if 'end of data' send null packet */
-
- if (len <= 0) {
- kwproto(fd,NULLP,0);
- return 0;
-
- /* expand 3 eight-bit bytes to four six-bit bytes */
-
- } else {
- for (rest = shift = i = 0; i < len; shift = (shift+STEP)%OUT,i++) {
-
- c = *buf++ & 0377; /* No sign extension */
- *packptr++ = tosix(rest|(c << shift)); /* Assemble byte */
- rest = (c >> (OUT-shift)); /* Save unused bits */
-
- if (shift == (OUT-STEP)) { /* At byte boundary? */
- *packptr++ = tosix(rest); /* Make 'fourth' byte */
- rest = 0; /* No unused bits now */
- if (packptr-packbuf > PACKSIZ-4) { /* Check packet size */
- kwproto(fd,packbuf,packptr-packbuf);
- packptr = packbuf;
- }
- }
- }
- if (shift) { /* Any bits left? */
- *packptr++ = tosix(rest); /* Put them there */
- }
- if (packptr > packbuf) { /* Flush buffer */
- kwproto(fd,packbuf,packptr-packbuf); /* Ship it off */
- packptr = packbuf;
- }
- return i;
- }
- }
-
- kread(fd,buf,len)
- int fd;
- char *buf;
- int len;
- {
- static char packbuf[MAXPACKSIZ] = "";
- static char *packptr = packbuf;
- static int packsiz = 0;
- register int i,c;
- static int shift,rest;
-
- /* set error trap */
-
- if (setjmp(Failbuf))
- return FAIL;
-
- /* read packet if buffer is empty */
-
- if (packsiz <= 0) {
- krproto(fd,packptr = packbuf,&packsiz);
- rest = shift = 0;
- }
-
- /* unpack (remainder of) buffer; return 0 if empty packet received */
-
- for (i = 0; (i < len) && packsiz--; shift = (shift+STEP)%IN)
- {
- c = unsix(*packptr++);
- if (shift)
- buf[i++] = (rest | (c << (IN-shift)));
- rest = (c >> shift);
- }
- return i;
- }
-
- kclose(fd)
- int fd;
- {
- /* not here - pass job to the lower layer that understands packet types */
-
- kclsproto(fd);
- return 0;
- }
-
-
-